package fm.shop.service.impl;

import com.mongodb.DBObject;
import fm.dao.MongoBaseDao;
import fm.exception.BizException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.nio.SemaphoreExecutor;
import fm.shop.service.SearchService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/**
 * @修改人：CM
 * @修改时间：2017/3/2 22:19
 */
@Service
public class SearchServiceImpl implements SearchService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchService.class);
    @Autowired
    private MongoBaseDao baseDao;

    /**
     *  TODO current version un-support chinese character search-req
     * @param keywords
     * @param tables
     * @return
     * @throws InterruptedException
     * @throws BizException
     */
    @Override
    public ConcurrentHashMap<String, Collection> searchByKeyword(final String keywords, Collection<String> tables) throws InterruptedException, BizException {
        if (CollectionUtils.isNotEmpty(tables)) {

            int size = tables.size() > 50 ? 50 : tables.size();
            final CountDownLatch cdl = new CountDownLatch(tables.size());
            final ConcurrentHashMap allData = new ConcurrentHashMap();
            SemaphoreExecutor executor = new SemaphoreExecutor(size, "searchThread");

            for (final String table : tables) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            MCondition mc = MCondition.create(MRel.search).append("$text", keywords);
                            DBObject condition = mc.toDBObject();
                            LOGGER.info("text search condition:{}", condition.toString());
                            Collection data = baseDao.getList(condition.toMap(), DBObject.class, table);
                            if (CollectionUtils.isNotEmpty(data)) {
                                allData.put(table, data);
                            }
                        } catch (Exception ex) {
                            LOGGER.error("search occur error", ex);
                        } finally {
                            cdl.countDown();
                        }
                    }
                });
            }
            cdl.await();

            return allData;
        }

        return null;
    }
}
